package name.huzhenbo.java.serialization;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Using custom serialized form, store only necessary logic information. Here we only need to store the size, and entry's data.
 */
class StringList implements Serializable {

    // Should be transient, otherwise the defaultwriteobject will serialize them, and also the readobject will read it 2 times, 
    // where the first time is in defaultReadObject.
    private transient int size = 0;

    private transient Entry head = null;

    private transient Entry tail = null;

    public int getSize() {
        return size;
    }

    public Entry getHead() {
        return head;
    }

    public void add(String data) {
        Entry entry = new Entry();
        entry.data = data;
        if (head == null) {
            head = entry;
        } else {
            Entry previousTail = tail;
            entry.previous = previousTail;
            previousTail.next = entry;
        }
        tail = entry;
        size++;
    }

    static class Entry {
        String data;
        Entry previous;
        Entry next = null;

        public String getData() {
            return data;
        }

        public Entry getPrevious() {
            return previous;
        }

        public Entry getNext() {
            return next;
        }
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeInt(size);

        for (Entry e = head; e != null; e = e.next) {
            s.writeObject(e.data);
        }
    }

    private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
        s.defaultReadObject();
        int numberElements = s.readInt();

        for (int i = 0; i < numberElements; i++) {
            add((String) s.readObject());
        }
    }
}
